﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.DataModel;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class HYPipeConnectEquipmentBatch : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			if (commandData == null)
			{
				throw new System.ArgumentNullException("commandData", "is null");
			}
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			Document document = activeUIDocument.Document;
			Selection selection = activeUIDocument.Selection;
			List<ViewType> viewTypes = YJKRevitTools.ListViewNeed(1);
			if (!YJKRevitTools.ViewCheck(activeUIDocument, viewTypes))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			Result result;
			try
			{
				ISelectionFilter selectionFilter = new PipeAndEquipmentSelectionFilter();
				ISelectionFilter selectionFilter2 = new PipeSelectionFilter();
				ISelectionFilter selectionFilter3 = new EquipmentSelectionFilter();
				HYPipeConnect hypipeConnect = new HYPipeConnect();
				new ConnectHelper();
				new HVACUserSetting().GetEquipmentCoilSetText();
				string text = "水管连接设备";
				int num = 0;
				transaction = new Transaction(document, text);
				transaction.Start();
				CoilConnectForm coilConnectForm = new CoilConnectForm(document);
				coilConnectForm.ShowDialog();
				if (coilConnectForm.DialogResult == DialogResult.OK)
				{
					for (;;)
					{
						SubTransaction subTransaction = new SubTransaction(document);
						try
						{
							try
							{
								if (num != 0)
								{
									RevitVersionFuncs.ClearSelection(selection);
								}
								num++;
								IList<Pipe> list = new List<Pipe>();
								IList<FamilyInstance> list2 = new List<FamilyInstance>();
								FamilyInstance familyInstance = null;
								new List<Element>();
								IList<Element> list3 = new List<Element>();
								IList<Element> list4 = new List<Element>();
								if (selection.GetElementIds().Any<ElementId>())
								{
									foreach (ElementId elementId in selection.GetElementIds())
									{
										list3.Add(document.GetElementById(elementId));
									}
								}
								bool flag = true;
								bool flag2 = true;
								foreach (Element element in list3)
								{
									if (element is Pipe)
									{
										list4.Add(element);
										flag = false;
									}
									else if (-2001140 == element.Category.Id.IntegerValue)
									{
										list4.Add(element);
										flag2 = false;
									}
								}
								RevitVersionFuncs.ClearSelection(selection);
								if (flag && flag2)
								{
									IEnumerator<Element> enumerator2 = selection.PickElementsByRectangle(selectionFilter, "请框选水管和风机盘管").GetEnumerator();
									{
										while (enumerator2.MoveNext())
										{
											Element item = enumerator2.Current;
											list4.Add(item);
										}
										goto IL_26D;
									}
								}
								if (flag)
								{
									IEnumerator<Element> enumerator2 = selection.PickElementsByRectangle(selectionFilter2, "请框选水管").GetEnumerator();
									{
										while (enumerator2.MoveNext())
										{
											Element item2 = enumerator2.Current;
											list4.Add(item2);
										}
										goto IL_26D;
									}
								}
								if (flag2)
								{
									foreach (Element item3 in selection.PickElementsByRectangle(selectionFilter3, "请框选设备"))
									{
										list4.Add(item3);
									}
								}
								IL_26D:
								int num2 = 0;
								foreach (Element element2 in list4)
								{
									if (element2 is Pipe)
									{
										list.Add(element2 as Pipe);
									}
									else if (element2 is FamilyInstance)
									{
										list2.Add(element2 as FamilyInstance);
										familyInstance = (element2 as FamilyInstance);
										num2++;
									}
								}
								if (list.Count > 0)
								{
									List<Pipe> list5 = new List<Pipe>();
									for (int i = 0; i < list.Count; i++)
									{
										bool flag3 = false;
										int num3 = i + 1;
										while (num3 < list.Count && num3 < list.Count)
										{
											if ((list[i].MEPSystem as PipingSystem).SystemType == (list[num3].MEPSystem as PipingSystem).SystemType && list[i].Id != list[num3].Id)
											{
												flag3 = true;
												break;
											}
											num3++;
										}
										if (!flag3)
										{
											list5.Add(list[i]);
										}
									}
									list = list5;
								}
								subTransaction.Start();
								if (familyInstance != null || list.Count >= 1)
								{
									if (familyInstance == null || list.Count < 1)
									{
										MessageBox.Show("至少选择一个设备和水管", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
									}
									else if (num2 == 1)
									{
										int maxDistance = coilConnectForm.maxDistance;
										this.CheckEquipmentPosition(new List<FamilyInstance>
										{
											familyInstance
										}, ref list, maxDistance);
										if (list == null || list.Count < 1)
										{
											YJKMessageBox.Information("未找到可连接风机盘管！");
										}
										else if (coilConnectForm.connectionType == 0)
										{
											if (!hypipeConnect.NewBeatchPipeEquipment(familyInstance, ref list, coilConnectForm.BeFlex(), coilConnectForm.FlexLength, 1))
											{
												MessageBox.Show("连接失败", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
												subTransaction.RollBack();
												continue;
											}
										}
										else
										{
											double distance = 100.0;
											if (!hypipeConnect.ValveEquipmentConn(familyInstance, document, list, distance, coilConnectForm.accessory, coilConnectForm.BeFlex(), coilConnectForm.FlexLength))
											{
												MessageBox.Show("连接失败", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
												subTransaction.RollBack();
												continue;
											}
										}
									}
									else if (num2 > 1)
									{
										int maxDistance2 = coilConnectForm.maxDistance;
										this.CheckEquipmentPosition(list2, ref list, maxDistance2);
										if (list == null || list.Count < 1)
										{
											YJKMessageBox.Information("未找到可连接风机盘管！");
										}
										else
										{
											XYZ globalPnt = selection.PickPoint("选择系统起点……");
											hypipeConnect.BeathchConnPipeEquipment(ref list, list2.ToList<Element>(), 1, globalPnt, coilConnectForm.accessory, coilConnectForm.BeFlex(), coilConnectForm.FlexLength);
										}
									}
								}
								document.Regenerate();
								subTransaction.Commit();
							}
							catch (Autodesk.Revit.Exceptions.OperationCanceledException)
							{
								return Autodesk.Revit.UI.Result.Succeeded;
							}
							catch (Exception ex)
							{
								MessageBox.Show(ex.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Hand);
							}
							continue;
						}
						finally
						{
							if (subTransaction != null)
							{
								TransactionStatus status = subTransaction.GetStatus();
								if ((int)status == 1)
								{
									subTransaction.Commit();
								}
								else if ((int)status == 5)
								{
									subTransaction.RollBack();
								}
							}
						}
						break;
					}
				}
				if (coilConnectForm.DialogResult == DialogResult.Yes)
				{
					CoilTrackConnForm coilTrackConnForm = new CoilTrackConnForm(document);
					coilTrackConnForm.ShowDialog();
					if (coilTrackConnForm.DialogResult == DialogResult.OK)
					{
						for (;;)
						{
							try
							{
								CoilFanConnHelper coilFanConnHelper = new CoilFanConnHelper(document, selection);
								coilFanConnHelper.FSymbols = coilConnectForm.accessory;
								coilFanConnHelper.CoilConnSet = coilTrackConnForm.CoilConn;
								coilFanConnHelper.ConnectorSetId = coilTrackConnForm.ConnSetId;
								coilFanConnHelper.BFlex = coilConnectForm.bFlex;
								coilFanConnHelper.FlexLength = coilConnectForm.FlexLength;
								HYPipeConnect hypipeConnect2 = new HYPipeConnect();
								coilFanConnHelper.SupplyLength = hypipeConnect2.GetDistanceSystemTypeSet((Autodesk.Revit.DB.Plumbing.PipeSystemType)7);
								coilFanConnHelper.ReturnLength = hypipeConnect2.GetDistanceSystemTypeSet((Autodesk.Revit.DB.Plumbing.PipeSystemType)8);
								coilFanConnHelper.SanitaryLength = hypipeConnect2.GetDistanceSystemTypeSet((Autodesk.Revit.DB.Plumbing.PipeSystemType)22);
								coilFanConnHelper.SelectElementSet();
								if (coilFanConnHelper.CreatConnCoilPipes())
								{
									transaction.Commit();
									transaction = new Transaction(document, "风机盘管按路由连接");
									transaction.Start();
									if (!coilFanConnHelper.ConnCoilsAndPipes())
									{
										YJKMessageBox.Information("连接风盘失败。");
										transaction.RollBack();
									}
									continue;
								}
								throw new Exception("创建水管出错。");
							}
							catch (Exception ex2)
							{
								string message2 = ex2.Message;
								goto IL_6A8;
							}
							break;
						}
					}
					coilTrackConnForm.Close();
				}
				IL_6A8:
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex3)
			{
				MessageBox.Show(ex3.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Hand);
				this.EndTransation(transaction, false);
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				this.EndTransation(transaction, true);
			}
			return result;
		}

		private void EndTransation(Transaction tran, bool beSure)
		{
			if (tran != null)
			{
				TransactionStatus status = tran.GetStatus();
				if ((int)status == 1)
				{
					if (beSure)
					{
						tran.Commit();
						return;
					}
					tran.RollBack();
					return;
				}
				else if ((int)status == 5)
				{
					tran.RollBack();
				}
			}
		}

		private void CheckEquipmentPosition(IList<FamilyInstance> eqs, ref IList<Pipe> pipes, int distance = 600)
		{
			IList<Pipe> list = new List<Pipe>();
			foreach (FamilyInstance familyInstance in eqs)
			{
				Connector connector = (YJKRevitTools.GetElementAllConnector(familyInstance).Count > 0) ? YJKRevitTools.GetElementAllConnector(familyInstance)[0] : null;
				foreach (Pipe pipe in pipes)
				{
					HYPipeConnect hypipeConnect = new HYPipeConnect();
					PipeSystemType connPipeSystemType = hypipeConnect.GetConnPipeSystemType(pipe, familyInstance);
					if (connPipeSystemType != null)
					{
						double distanceSystemTypeSet = hypipeConnect.GetDistanceSystemTypeSet(connPipeSystemType);
						YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
						bool flag = false;
						if (connector != null && !connector.CoordinateSystem.BasisZ.IsAlmostEqualTo(hypiping.StartConnector.Connector.CoordinateSystem.BasisZ) && !connector.CoordinateSystem.BasisZ.IsAlmostEqualTo(-hypiping.StartConnector.Connector.CoordinateSystem.BasisZ))
						{
							if (list.Count < 1)
							{
								list.Add(pipe);
							}
							else
							{
								flag = false;
								IEnumerator<Pipe> enumerator3 = list.GetEnumerator();
								{
									while (enumerator3.MoveNext())
									{
										if (enumerator3.Current.UniqueId == pipe.UniqueId)
										{
											flag = true;
											break;
										}
									}
								}
								if (!flag)
								{
									list.Add(pipe);
								}
							}
						}
						else if (connector != null)
						{
							XYZ basisZ = connector.CoordinateSystem.BasisZ;
							XYZ point = connector.Origin + basisZ * distanceSystemTypeSet;
							XYZ project = hypiping.GetProject(point, true);
							if (!hypiping.IsPointOnPipingCurve(project))
							{
								XYZ startP = new XYZ();
								if (hypiping.StartConnector.Origin.DistanceTo(project) < hypiping.EndConnector.Origin.DistanceTo(project))
								{
									startP = hypiping.EndConnector.Origin;
								}
								else
								{
									startP = hypiping.StartConnector.Origin;
								}
								Pipe pipe2 = hypiping.Extend(startP, project);
								if (list.Count < 1)
								{
									list.Add(pipe2);
								}
								else
								{
									flag = false;
									IEnumerator<Pipe> enumerator3 = list.GetEnumerator();
									{
										while (enumerator3.MoveNext())
										{
											if (enumerator3.Current.UniqueId == pipe2.UniqueId)
											{
												flag = true;
												break;
											}
										}
									}
									if (!flag)
									{
										list.Add(pipe2);
									}
								}
							}
							else if (list.Count < 1)
							{
								list.Add(pipe);
							}
							else
							{
								flag = false;
								IEnumerator<Pipe> enumerator3 = list.GetEnumerator();
								{
									while (enumerator3.MoveNext())
									{
										if (enumerator3.Current.UniqueId == pipe.UniqueId)
										{
											flag = true;
											break;
										}
									}
								}
								if (!flag)
								{
									list.Add(pipe);
								}
							}
						}
						else if (list.Count < 1)
						{
							list.Add(pipe);
						}
						else
						{
							flag = false;
							IEnumerator<Pipe> enumerator3 = list.GetEnumerator();
							{
								while (enumerator3.MoveNext())
								{
									if (enumerator3.Current.UniqueId == pipe.UniqueId)
									{
										flag = true;
										break;
									}
								}
							}
							if (!flag)
							{
								list.Add(pipe);
							}
						}
					}
				}
			}
			pipes = list;
		}
	}
}
